﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using Flagwind.Reflection;

namespace Flagwind.ComponentModel
{
	/// <summary>
	/// 数据传输对象基类。
	/// </summary>
	[Serializable]
	public abstract class DataObject : IDataObject
	{
		#region 公共方法

		/// <summary>
		/// 获取当前数据传输对象的验证错误信息。
		/// </summary>
		/// <returns></returns>
		public IEnumerable<ValidationResult> GetValidationErrors()
		{
			return this.Validate();
		}

		/// <summary>
		/// 转换字典
		/// </summary>
		/// <returns></returns>
		public SortedDictionary<string, object> ToDictionary()
		{
			Type type = this.GetType();

			var properties = RequestInstructionProperties.GetDictionary(type.FullName) as PropertyInfo[];

			if(properties == null)
			{
				//获取指定名称的属性
				properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);

				RequestInstructionProperties.SetDictionary(type.FullName, properties);
			}

			var result = new SortedDictionary<string, object>();

			foreach(var item in properties)
			{
				var val = item.GetValue(this);

				#region 属性为时间类型 格式 "2017-04-12 00:00:00"

				if(item.PropertyType == typeof(DateTime) || item.PropertyType == typeof(DateTime?))
				{
					//检查值是否为null
					if(val != null)
					{
						val = DateTime.Parse(val.ToString()).ToString("yyyy-MM-dd HH:mm:ss");
					}
				}

				#endregion

				#region 属性为引用类型

				else if(!item.PropertyType.IsValueType && item.PropertyType != typeof(string))
				{
					//检查值是否为null
					if(val != null)
					{
						val = Flagwind.Runtime.Serialization.Serializer.Json.Serialize(val);
					}
				}

				#endregion

				result.Add(item.Name, val);
			}

			return result;
		}

		#endregion

		#region 保护方法

		/// <summary>
		/// 确定当前对象是否有效。
		/// </summary>
		/// <returns>包含失败的验证信息的集合。</returns>
		protected virtual IEnumerable<ValidationResult> Validate()
		{
			return new List<ValidationResult>();
		}

		#endregion

		#region 内部类

		public static class RequestInstructionProperties
		{
			public static Dictionary<string, object> dicProperties = new Dictionary<string, object>();

			/// <summary>
			/// 获取所有属性名称
			/// </summary>
			/// <param name="key"></param>
			/// <returns></returns>
			public static object GetDictionary(string key)
			{
				if(dicProperties.Keys.Contains(key))
					return dicProperties[key];
				else
					return null;
			}

			/// <summary>
			/// 设置所有属性名称
			/// </summary>
			/// <param name="key"></param>
			/// <param name="data"></param>
			public static void SetDictionary(string key, object data)
			{
				if(dicProperties.Keys.Contains(key))
					dicProperties.Remove(key);

				dicProperties.Add(key, data);
			}
		}

		#endregion
	}
}